
class processpool
{
public:
    processpool(int num):_processnum(num)
    {
    }
    void Init()
    {
        for (int i = 0; i < _processnum; i++)
        {
            // 创建匿名管道，再被子进程继承，父子进程看到同一份资源
            int pipefd[2] = {0};
            //int n = ::pipe2(pipefd,O_NONBLOCK);
            int n = ::pipe(pipefd);

            if (n == 0) // 管道创建成功
            {
                pid_t id = fork(); // 创建子进程，子进程继承父进程的读写端
                if (id > 0) // 父进程
                {
                    ::close(pipefd[0]); // 父进程关闭读端
                    //std::cout << "pipefd[1]" << pipefd[1] << "if:" << id << std::endl;
                    _ch.emplace_back(pipefd[1], id);
                }
                else if (id == 0) // 子进程
                {
                    //std::cout << "子进程创建成功" << std::endl;
                    ::close(pipefd[1]); // 子进程关闭写端，父进程派发任务，子进程来执行任务
                    for(auto &e : _ch)
                    {
                        e.close();//关闭上一个子进程打开的读端
                    }
                    while (true)
                    {
                        int taski;
                        //std::cout << "我在阻塞" << std::endl;
                        ssize_t n = ::read(pipefd[0], &taski, sizeof(taski));
                        //std::cout << "我没有阻塞" << std::endl;
                        if (n == sizeof(taski))
                        {
                            gtask.Execute(taski);
                        }
                        else if (n == 0)
                        {
                            std::cout << "pid: " << getpid() << " quit..." << std::endl;
                            break;
                        }
                        else
                        {
                        }
                        //std::cout << n << std::endl;
                        //sleep(2);

                    }
                    ::exit(0);
                }
                else
                {
                    std::cout << "创建子进程失败" << std::endl;
                    ::exit(FORKERR);
                }
            }
            else // 管道创建失败，错误码被设置
            {
                std::cout << "PIPEERR，err code : " << errno << std::endl;
                ::exit(PIPEERR);
            }
            sleep(1);
        }
    }
    void Dispatch()
    {
        int who = 0;
        int num = 20;//任务数量
        while(num--)
        {
            int task = gtask.DispatchTask();
            Channel &curr = _ch[who++];
            who %= _ch.size();

            std::cout << "######################" << std::endl;
            std::cout << "send task : " << task << " to " << curr.name() << ", 任务还剩: " << num << std::endl;
            std::cout << "######################" << std::endl;

            curr.send(task);

            sleep(1);

        }
    }
    void CloseProcesspool()
    {
        for(auto &channel : _ch)//关闭打开的管道的写端
        {
            channel.close();
            pid_t wid = waitpid(channel.Getpid(), nullptr, 0);
            if (wid > 0)
            {
                std::cout << "等待子进程成功" << std::endl;
            }
        }
        // for (int i = _ch.size() - 1; i >= 0; i--)
        // {
        //     _ch[i].close();
        //     pid_t wid = waitpid(_ch[i].Getpid(), nullptr, 0);
        //     if (wid > 0)
        //     {
        //         std::cout << "等待子进程成功" << std::endl;
        //     }
        // }
    }
    ~processpool()
    {}

private:
    std::vector<Channel> _ch;
    int _processnum;
};